#version 330 core

struct Material
{
    vec3 ambient;
    vec3 diffuse;
    vec3 specular;
    float shininess;
    bool useDiffuseTex;  // 控制是否用漫反射纹理
    bool useSpecularTex; // 控制是否用镜面纹理
    bool useNormalTex;   // 控制是否用法线纹理
};

struct Light
{
    int type; // 0:方向光, 1:点光, 2:聚光灯
    vec3 color;
    vec3 position;
    vec3 direction;
    float constant;
    float linear;
    float quadratic;
    float cutOff;    // 弧度的余弦值
    float outerCutOff;
};

in vec3 vertexColor;
in vec3 Norm;
in vec3 FragPos;
in vec2 TexCoords;
in mat3 TBN;

out vec4 FragColor;

#define MAX_LIGHTS 10
uniform Light lights[MAX_LIGHTS];
uniform int lightCount;
uniform vec3 viewPos;
uniform Material material;

uniform sampler2D diffuseSampler;  // 漫反射纹理（GL_TEXTURE0）
uniform sampler2D specularSampler; // 镜面纹理（GL_TEXTURE1）
uniform sampler2D normalSampler;   // 法线纹理（GL_TEXTURE2）

uniform bool grayValueMode, pureColorMode;

// 计算修正后的法线（复用，避免冗余）
vec3 getCorrectedNormal()
{
    if (!material.useNormalTex)
    {
        return normalize(Norm);
    }
    vec3 normalTex = texture(normalSampler, TexCoords).rgb;
    normalTex = normalize(normalTex * 2.0 - 1.0);
    return normalize(TBN * normalTex);
}

vec3 calculateLightContribution(Light light, vec3 norm, vec3 fragPos, vec3 viewDir)
{
    // 1. 采样纹理颜色（统一用 material.useDiffuseTex 控制）
    vec3 diffColor = material.useDiffuseTex ?
        texture(diffuseSampler, TexCoords).rgb : vertexColor; // 无纹理用顶点颜色
    vec3 specColor = material.useSpecularTex ?
        texture(specularSampler, TexCoords).rgb : material.specular;

    // 2. 环境光（用漫反射纹理颜色）
    vec3 ambient = light.color * 0.2 * material.ambient * diffColor;

    // 3. 光源方向与衰减
    vec3 lightDir;
    float attenuation = 1.0;
    float spotFactor = 1.0;

    if (light.type == 0)
    {
        lightDir = normalize(-light.direction);
    }
    else if (light.type == 1)
    {
        lightDir = normalize(light.position - fragPos);
        float dist = length(light.position - fragPos);
        attenuation = 1.0 / (light.constant + light.linear * dist + light.quadratic * dist * dist);
    }
    else if (light.type == 2)
    {
        lightDir = normalize(light.position - fragPos);
        float theta = dot(lightDir, normalize(-light.direction));
        float epsilon = light.cutOff - light.outerCutOff;
        spotFactor = clamp((theta - light.outerCutOff) / epsilon, 0.0, 1.0);
        float dist = length(light.position - fragPos);
        attenuation = 1.0 / (light.constant + light.linear * dist + light.quadratic * dist * dist);
    }

    // 4. 漫反射与镜面反射（用采样后的颜色）
    float diff = max(dot(norm, lightDir), 0.0);
    vec3 diffuse = light.color * diff * material.diffuse * diffColor;

    vec3 reflectDir = reflect(-lightDir, norm);
    float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);
    vec3 specular = light.color * spec * specColor;

    // 5. 应用衰减和聚光灯因子
    ambient *= attenuation;
    diffuse *= attenuation * spotFactor;
    specular *= attenuation * spotFactor;

    return ambient + diffuse + specular;
}

vec3 calculateDefaultLighting(Material material, vec3 norm, vec3 viewDir)
{
    // 1. 默认方向光（左上→右下，确保所有面都有明暗差异）
    vec3 lightColor = vec3(1.0); // 柔和白光
    vec3 lightDir = normalize(viewDir);

    // 2. 采样纹理（关键：支持有纹理的模型，如GLB）
    vec3 diffColor = material.useDiffuseTex ?
        texture(diffuseSampler, TexCoords).rgb : vertexColor;
    vec3 specColor = material.useSpecularTex ?
        texture(specularSampler, TexCoords).rgb : material.specular;

    // 3. 默认材质参数（优先用模型材质，否则用默认值）
    vec3 matAmbient = material.ambient == vec3(0) ? vec3(0.2) : material.ambient;
    vec3 matDiffuse = material.diffuse == vec3(0) ? vec3(0.8) : material.diffuse;
    vec3 matSpecular = material.specular == vec3(0) ? vec3(0.5) : material.specular;
    float matShininess = material.shininess <= 0 ? 32.0 : material.shininess;

    // 4. 光照计算（复用逻辑，确保纹理和顶点颜色都生效）
    vec3 ambient = lightColor * matAmbient * diffColor;
    float diff = max(dot(norm, lightDir), 0.0);
    vec3 diffuse = lightColor * (diff * matDiffuse) * diffColor;
    vec3 reflectDir = reflect(-lightDir, norm);
    float spec = pow(max(dot(viewDir, reflectDir), 0.0), matShininess);
    vec3 specular = lightColor * (spec * specColor);

    return ambient + diffuse + specular;
}

void main()
{
    // 1. 获取修正后的法线
    vec3 norm = getCorrectedNormal();

    // 2. 计算视线方向
    vec3 viewDir = normalize(viewPos - FragPos);

    // 3. 光照计算
    vec3 result = vec3(0.0);
    if (lightCount > 0 && lightCount <= MAX_LIGHTS)
    {
        for (int i = 0; i < lightCount; i++)
        {
            result += calculateLightContribution(lights[i], norm, FragPos, viewDir);
        }
    }
    else
    {
        // 无光源时，用顶点颜色
        result = calculateDefaultLighting(material, norm, viewDir);;
    }

    // 灰度模式
    if (grayValueMode)
    {
        float gray = vertexColor.r; // 已经预计算好的灰度值
        result = vec3(gray);
    }

    if (pureColorMode)
    {
        // 计算当前片元的亮度（保持明暗变化）
        float brightness = dot(result, vec3(0.299, 0.587, 0.114));
        // 用统一颜色乘以亮度，保持明暗关系
        result = vertexColor * brightness;
    }

    FragColor = vec4(result, 1.0);
}

//void main()
//{
//    FragColor = vec4(vertexColor, 1.0);
//}
